<?php


namespace XiaoGuai\DataStructure\Stack\LinkedStack;


use XiaoGuai\DataStructure\Stack\StackInterface;
use XiaoGuai\DataStructure\Stack\LinkedStack\LinkedStackNode as Node;

/**
 * 栈的链式存储表示
 * Class LinkedStack
 * @package XiaoGuai\DataStructure\StackInterface\LinkedStack
 */
class LinkedStack implements StackInterface
{
    /**
     * @var null|Node 头指针
     */
    protected $top = null;

    /**
     * @var int 栈存储元素的长度
     */
    protected $length = 0;

    public function __construct()
    {
        $this->top = null;
    }

    /**
     * 向栈中压入元素
     * @param $element
     * @return bool
     */
    public function push($element): bool
    {
        $node = new Node();
        $node->data = $element;
        $node->next = $this->top;

        $this->top = $node;
        $this->length++;
        return true;
    }

    /**
     * 从栈中弹出元素
     * @return mixed
     */
    public function pop()
    {
        if (is_null($this->top)) {
            throw new \Exception('overflow');
        }

        $element = $this->top->data;
        $this->top = $this->top->next;
        $this->length--;
        return $element;
    }

    /**
     * 返回当前栈顶元素
     * @return mixed
     */
    public function top()
    {
        if (is_null($this->top)) {
            throw new \Exception('overflow');
        }

        return $this->top->data;
    }

    /**
     * 栈是否为空
     * @return bool
     */
    public function isEmpty(): bool
    {
        return is_null($this->top);
    }

    /**
     * 栈当前存储的元素个数
     * @return int
     */
    public function length(): int
    {
        return $this->length;
    }
}